package com.trying.simpleioc.util;

import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.net.URL;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Set;

import org.apache.log4j.Logger;
/**
 * 类文件加载工具
 * @author dimi
 *
 */
public class ClassUtil {
	private static final Logger log=Logger.getLogger(ReflectionUtil.class);

	private ClassUtil(){}
	/**
	 * 获取类加载器
	 */
	public static ClassLoader getClassLoader(){
		return Thread.currentThread().getContextClassLoader();
	}

	
	/**
	 *加载一个类 
	 */
	public static Class<?> loadClass(String className,boolean isInitialized){
		Class<?> cls=null;
		try {
			cls=Class.forName(className,isInitialized,getClassLoader());
		} catch (ClassNotFoundException e) {
			log.error(e);
		}
		return cls;
	}
	/**
	 * 根据给定的包名获得包下的类集合
	 * @param packageName  需要扫描的包名格式为：com.company.project
	 */
	public static Set<Class<?>> getClassSet(String packageName){
		Set<Class<?>> classSet=new HashSet<Class<?>>();
		
		try {
			Enumeration<URL> urls=getClassLoader().getResources(packageName.replace(".", "/"));
			while(urls.hasMoreElements()){
				URL url=urls.nextElement();
				if(url!=null){
					String protocol=url.getProtocol();
					if(protocol.equals("file")){
						String packagePath=url.getPath().replaceAll("%20"," ");
						addClass(classSet,packagePath,packageName);
					}else if(protocol.equals("jar")){
						//未实现
					}
				}
			}
			
		} catch (IOException e) {
			log.error(e);
		}
		
		return classSet;
	}
	
	

	/**
	 * 递归添加类以及子文件夹中的类
	 * @param classSet
	 * @param packagePath
	 * @param packageName
	 */
	public static void addClass(Set<Class<?>> classSet,String packagePath,String packageName){
		File[]  files=new File(packagePath).listFiles(new FileFilter(){
			public boolean accept(File file){
				return (file.isFile()&&file.getName().endsWith(".class"))
				||file.isDirectory();
			}
		});
		for(File file:files){
			String fileName=file.getName();
			if(file.isFile()){
				String className=fileName.substring(0,fileName.lastIndexOf("."));
				if(packageName!=null&&!packageName.isEmpty()){
					className=packageName+"."+className;
				}
				doAddClass(classSet,className);
			}else if(file.isDirectory()){
				addClass(classSet,file.getPath().replaceAll("%20"," "),packageName+"."+file.getName());
			}
		}
	}


	private static void doAddClass(Set<Class<?>> classSet, String className) {
		Class<?> cls=loadClass(className,false);
		classSet.add(cls);
	}
	
}
